﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.XPath;
using System.Xml.Xsl;
using WebPartPageParser;

namespace DataViewWebPartDocumenter
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        //Global Variables
        private string siteURL = "";   
        private const string ASPX = ".aspx";
        private const string XML = ".xml";
        private const string HTML = ".html";
        private const string SITES = "/sites/";
        private const string PARSER_XSL = "./DataFiles/parser.xsl";
        private const string WEBPARTPAGESERVICE = "/_vti_bin/webpartpages.asmx";
        private const string ASSEMBLY = "<%@ Assembly";
        private const string DVWP_DOC_FOLDER = @"\DVWPDocumenter";

        public MainWindow()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Handle when Site URL change occurs and validates URL
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtBoxSiteURL_TextChanged(object sender, TextChangedEventArgs e)
        {
            ValidateInput();
        }

        /// <summary>
        /// Handle When Text Change Occurs and validates URL
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtBoxDVWP_TextChanged(object sender, TextChangedEventArgs e)
        {
            ValidateInput();
        }

        /// <summary>
        /// Validates both text box inputs for URI
        /// </summary>
        private void ValidateInput()
        {
            //Check if valid System.URI
            bool validURI = false;

            try
            {
                //Test if meets URI 
                Uri uriTest = new Uri(txtBoxDVWP.Text.ToString());
                Uri uriTest2 = new Uri(txtBoxSiteURL.Text.ToString());

                //If DVWP URL ends with .aspx and site url doesn't assume we have a valid URI
                //Note: this is not a perfect check but good enough for now.
                if (txtBoxDVWP.Text.ToString().EndsWith(ASPX) == true && txtBoxSiteURL.Text.ToString().EndsWith(ASPX) == false)
                {
                    validURI = true;
                }
            }
            catch (Exception uriException)
            {
                //Do nothing validURI will be false
            }

            if (validURI == true) //Checks if url is correct
            {
                //Enable button
                btnGenerateDocument.IsEnabled = true;
                chkBoxTransform.IsEnabled = true;

                //Set site URL
                siteURL = txtBoxSiteURL.Text.ToString();
            }
            else
            {
                //Disable button
                btnGenerateDocument.IsEnabled = false;
                chkBoxTransform.IsEnabled = false;

                //Clear out global variable
                siteURL = "";
            }
        }


        /// <summary>
        /// Generate Documentation.  In the future, move parsing to separate thread for repsonsive UI.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnGenerateDocument_Click(object sender, RoutedEventArgs e)
        {
            //Disable controls while parser is running
            btnGenerateDocument.IsEnabled = false;
            txtBoxDVWP.IsEnabled = false;
            txtBoxSiteURL.IsEnabled = false;
            chkBoxTransform.IsEnabled = false;

            //Initialize Parser Function
            Parser parser = new Parser();

            //See if checkbox for transformation is check
            bool isTransformEnabled = chkBoxTransform.IsChecked.Value;

            try
            {
                //CALL WEB SERVICE
                string result = CallWebService(txtBoxDVWP.Text.ToString());
                              
                
                //Look for first assembly reference that should be the start of the aspx page
                int index = result.IndexOf(ASSEMBLY);

                if (index != -1) //If found write out file.
                {

                    //SAVE FILE
                    string tempFileInput = SaveFile(index, result);

                    //PARSE FILE
                    Parser parserX = new Parser();
                    DVWPPage dvwpPage = parserX.ParseFile(tempFileInput);

                    //PRODUCE OUTPUT
                    string tempFileOutput = ProductOutput(isTransformEnabled, tempFileInput, dvwpPage);

                    //OPEN FILE with default file
                    Process.Start(tempFileOutput);

                }
                else
                {
                    MessageBox.Show("ASPX file can be found.");
                }

            }
            catch (Exception ex)
            {
                //Show Message
                MessageBox.Show(ex.Message);
            }
            finally
            {
                //Enable buttons
                btnGenerateDocument.IsEnabled = true;
                txtBoxDVWP.IsEnabled = true;
                txtBoxSiteURL.IsEnabled = true;
                chkBoxTransform.IsEnabled = true;
            }
        }//end on button click

        /// <summary>
        /// Save output of parsed file
        /// </summary>
        /// <param name="isTransformEnabled"></param>
        /// <param name="tempFileInput"></param>
        private string ProductOutput(bool isTransformEnabled, string tempFileInput, DVWPPage dvwpPage)
        {
            //Output File
            string tempFileOutput = "";

            //Save XML
            //Build output file
            tempFileOutput = tempFileInput.Replace(ASPX,XML);

            //Buid XML output
            XmlAttributeOverrides ov = new XmlAttributeOverrides();

            XmlSerializer x = new XmlSerializer(dvwpPage.GetType(), ov);

            //Write to XML
            using (XmlTextWriter writer = new XmlTextWriter(tempFileOutput, System.Text.UTF8Encoding.UTF8))
            {
                writer.WriteStartDocument();
                x.Serialize(writer, dvwpPage);
                writer.WriteEndDocument();

            }

            //If true write to HTML
            if (isTransformEnabled == true)//Transform to HTML based on parser.xsl
            {
                //Transform file
                XPathDocument myXPathDoc = new XPathDocument(tempFileOutput);
                XslCompiledTransform myXslTrans = new XslCompiledTransform();
                myXslTrans.Load(PARSER_XSL);

                //Save file with .html extension
                tempFileOutput = tempFileOutput.Replace(XML,HTML);

                //Output file
                using(XmlTextWriter writer2 = new XmlTextWriter(tempFileOutput,null))
                {
                    myXslTrans.Transform(myXPathDoc, null, writer2);
                }

                
                
            }
              


            return tempFileOutput;
        }

        /// <summary>
        /// Save file based on str input (SOAP response)
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private string SaveFile(int index, string result)
        {

            //Retrieve context
            string fileContent = result.Substring(index);

            //Create temporary directory
            string tempDirectory = System.Environment.GetEnvironmentVariable("TEMP") + DVWP_DOC_FOLDER + DateTime.Today.ToFileTimeUtc();

            //Create Directory
            System.IO.Directory.CreateDirectory(tempDirectory);

            // Temporary File Name
            string tempFileName = tempDirectory + @"\" + txtBoxDVWP.Text.Substring(txtBoxDVWP.Text.LastIndexOf("/") + 1);

            //Write File Contains Out
            using (System.IO.StreamWriter fS = new System.IO.StreamWriter(tempFileName))
            {
                fS.Write(fileContent);
                fS.Close();
            }

            //Return the file name from temp directory
            return tempFileName;
        }

        /// <summary>
        /// Call WebPartPages webservice
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private string CallWebService(string str)
        {
            //Build web service class to make call
            string inputStr = str;
            if (inputStr.Contains(SITES))
            {
                inputStr = inputStr.Substring(inputStr.IndexOf(SITES));
            }
            else
            {
                inputStr = inputStr.Substring(inputStr.IndexOf(siteURL) + siteURL.Length);
            }

            //Setup Web Service
            WebPartPagesWebService.WebPartPagesWebService service = new WebPartPagesWebService.WebPartPagesWebService();
            service.Url = siteURL + WEBPARTPAGESERVICE;
            service.UseDefaultCredentials = true;

            //Call service
            string result = service.GetWebPartPage(inputStr, WebPartPagesWebService.SPWebServiceBehavior.Version3);

            return result;
        }

 

    }//end class
}//end namespace
